/**
* \file Piece.c
* \author Fadime MERT / Maite MONNOT / Camille MORIN
* \version 1.0
* \date 27 mai 2010
* \brief Fichier contenant les fonctions pour initialiser la piece et tourner la piece 
*/

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

#include "Piece.h"

/* les differents void Init, on initialise les differentes pieces
dans des positions differentes pieces qui seront utilisee pour mettre
une nouvelle piece sur le terrain*/

/**
* \brief Cree un pointeur sur Piece avec un malloc
* \return Un pointeur sur \e Piece
*/
Piece * CreerPiece()
{
	Piece *pPiece;
	/*on alloue un espace dans la memoire */
	pPiece= (Piece *)malloc(sizeof(Piece));
	return pPiece;
}

/**
* \brief Initialise la piece de forme L droite
* \details Piece representant un tableau 4*4
* on definit l'etat de chaque case du tableau 
* \param p Pointeur sur Piece
*/
void InitLD(Piece* p)
{
	/*
	[_*__]
	[_*__]
	[_**_]
	[____]   */
	p->tableau[0][0]=VIDE ;
	p->tableau[0][1]=MOUVEMENT ;
	p->tableau[0][2]=VIDE ;
	p->tableau[0][3]=VIDE ;

	p->tableau[1][0]=VIDE ;
	p->tableau[1][1]=MOUVEMENT ;
	p->tableau[1][2]=VIDE ;
	p->tableau[1][3]=VIDE ;

	p->tableau[2][0]=VIDE ;
	p->tableau[2][1]=MOUVEMENT ;
	p->tableau[2][2]=MOUVEMENT ;
	p->tableau[2][3]=VIDE ;

	p->tableau[3][0]=VIDE ;
	p->tableau[3][1]=VIDE ;
	p->tableau[3][2]=VIDE ;
	p->tableau[3][3]=VIDE ;
}


/**
* \brief Initialise la piece de forme L gauche
* \details Piece representant un tableau 4*4
* on definit l'etat de chaque case du tableau 
* \param p Pointeur sur Piece
*/
void InitLG(Piece* p)
{
	/*
	[__*_]
	[__*_]
	[_**_]
	[____]   */
	p->tableau[0][0]=VIDE ;
	p->tableau[0][1]=VIDE ;
	p->tableau[0][2]=MOUVEMENT ;
	p->tableau[0][3]=VIDE ;

	p->tableau[1][0]=VIDE ;
	p->tableau[1][1]=VIDE ;
	p->tableau[1][2]=MOUVEMENT ;
	p->tableau[1][3]=VIDE ;

	p->tableau[2][0]=VIDE ;
	p->tableau[2][1]=MOUVEMENT ;
	p->tableau[2][2]=MOUVEMENT ;
	p->tableau[2][3]=VIDE ;

	p->tableau[3][0]=VIDE ;
	p->tableau[3][1]=VIDE ;
	p->tableau[3][2]=VIDE ;
	p->tableau[3][3]=VIDE ;
}


/**
* \brief Initialise la piece de forme Z droite
* \details Piece representant un tableau 4*4
* on definit l'etat de chaque case du tableau 
* \param p Pointeur sur Piece
*/
void InitZD(Piece* p)
{
	/*
	[____]
	[__**]
	[_**_]
	[____]   */
	p->tableau[0][0]=VIDE ;
	p->tableau[0][1]=VIDE ;
	p->tableau[0][2]=VIDE ;
	p->tableau[0][3]=VIDE ;

	p->tableau[1][0]=VIDE ;
	p->tableau[1][1]=VIDE ;
	p->tableau[1][2]=MOUVEMENT ;
	p->tableau[1][3]=MOUVEMENT ;

	p->tableau[2][0]=VIDE ;
	p->tableau[2][1]=MOUVEMENT ;
	p->tableau[2][2]=MOUVEMENT ;
	p->tableau[2][3]=VIDE ;

	p->tableau[3][0]=VIDE ;
	p->tableau[3][1]=VIDE ;
	p->tableau[3][2]=VIDE ;
	p->tableau[3][3]=VIDE ;
}


/**
* \brief Initialise la piece de forme Z gauche
* \details Piece representant un tableau 4*4
* on definit l'etat de chaque case du tableau 
* \param p Pointeur sur Piece
*/
void InitZG(Piece* p)
{
	/*
	[____]
	[**__]
	[_**_]
	[____]   */
	p->tableau[0][0]=VIDE;
	p->tableau[0][1]=VIDE;
	p->tableau[0][2]=VIDE ;
	p->tableau[0][3]=VIDE ;

	p->tableau[1][0]=MOUVEMENT ;
	p->tableau[1][1]=MOUVEMENT ;
	p->tableau[1][2]=VIDE ;
	p->tableau[1][3]=VIDE ;

	p->tableau[2][0]=VIDE ;
	p->tableau[2][1]=MOUVEMENT ;
	p->tableau[2][2]=MOUVEMENT ;
	p->tableau[2][3]=VIDE ;

	p->tableau[3][0]=VIDE ;
	p->tableau[3][1]=VIDE ;
	p->tableau[3][2]=VIDE ;
	p->tableau[3][3]=VIDE ;
}


/**
* \brief Initialise la piece de forme carre
* \details Piece representant un tableau 4*4
* on definit l'etat de chaque case du tableau 
* \param p Pointeur sur Piece
*/
void InitCarre(Piece* p)
{
	/*
	[____]
	[_**_]
	[_**_]
	[____]   */
	p->tableau[0][0]=VIDE ;
	p->tableau[0][1]=VIDE ;
	p->tableau[0][2]=VIDE ;
	p->tableau[0][3]=VIDE ;

	p->tableau[1][0]=VIDE ;
	p->tableau[1][1]=MOUVEMENT ;
	p->tableau[1][2]=MOUVEMENT ;
	p->tableau[1][3]=VIDE ;

	p->tableau[2][0]=VIDE ;
	p->tableau[2][1]=MOUVEMENT ;
	p->tableau[2][2]=MOUVEMENT ;
	p->tableau[2][3]=VIDE ;

	p->tableau[3][0]=VIDE ;
	p->tableau[3][1]=VIDE ;
	p->tableau[3][2]=VIDE ;
	p->tableau[3][3]=VIDE ;
}


/**
* \brief Initialise la piece de forme barre
* \details Piece representant un tableau 4*4
* on definit l'etat de chaque case du tableau
* \param p Pointeur sur Piece
*/
void InitBarre(Piece* p)
{
	/*
	[_*__]
	[_*__]
	[_*__]
	[_*__]   */
	p->tableau[0][0]=VIDE ;
	p->tableau[0][1]=MOUVEMENT ;
	p->tableau[0][2]=VIDE ;
	p->tableau[0][3]=VIDE ;

	p->tableau[1][0]=VIDE ;
	p->tableau[1][1]=MOUVEMENT ;
	p->tableau[1][2]=VIDE ;
	p->tableau[1][3]=VIDE ;

	p->tableau[2][0]=VIDE ;
	p->tableau[2][1]=MOUVEMENT ;
	p->tableau[2][2]=VIDE ;
	p->tableau[2][3]=VIDE ;

	p->tableau[3][0]=VIDE ;
	p->tableau[3][1]=MOUVEMENT ;
	p->tableau[3][2]=VIDE ;
	p->tableau[3][3]=VIDE ;
}


/**
* \brief Initialise la piece de forme T
* \details Piece representant un tableau 4*4
* on definit l'etat de chaque case du tableau 
* \param p Pointeur sur Piece
*/
void InitT(Piece* p)
{
	/*
	[____]
	[_*__]
	[***_]
	[____]   */
	p->tableau[0][0]=VIDE ;
	p->tableau[0][1]=VIDE ;
	p->tableau[0][2]=VIDE ;
	p->tableau[0][3]=VIDE ;

	p->tableau[1][0]=VIDE ;
	p->tableau[1][1]=MOUVEMENT ;
	p->tableau[1][2]=VIDE ;
	p->tableau[1][3]=VIDE ;

	p->tableau[2][0]=MOUVEMENT ;
	p->tableau[2][1]=MOUVEMENT ;
	p->tableau[2][2]=MOUVEMENT ;
	p->tableau[2][3]=VIDE ;

	p->tableau[3][0]=VIDE ;
	p->tableau[3][1]=VIDE ;
	p->tableau[3][2]=VIDE ;
	p->tableau[3][3]=VIDE ;
}


/**
 * \fn static int rand_a_b(int a, int b)
 * \brief Choisi un entier aleatoirement
 * \param a Entier
 * \param b Entier
 * \return Un \e entier dans l'intervalle [a,b[
 */
/* Choisi un entier aleatoirement dans l'intervalle [a,b[ */

static int rand_a_b(int a, int b)
{
	return rand()%(b-a)+a;
}


/**
* \brief Initialise une piece choisie aleatoirement
* \param p Pointeur sur Piece
*/
void InitPiece(Piece* p)
{
	/* choisi un chiffre aleatoirement entre  1 et 7*/

	int choix;
	choix = rand_a_b(1,8);

	/*chaque chiffre correspond a une piece */

	switch(choix)
	{
		case 1: InitLD(p);
		break;

		case 2: InitLG(p);
		break;

		case 3: InitZD(p);
		break;

		case 4: InitZG(p);
		break;

		case 5: InitCarre(p);
		break;

		case 6: InitBarre(p);
		break;

		case 7: InitT(p);
		break;
	}
}



/**
* \brief Tourne la piece de 90 degres
* \param p Pointeur sur Piece
*/
void TournerPiece(Piece * p)
{
	int i,j;
	Etat tmp[4][4];

	/* on recopie la piece dans un tableau */

	for(i=0;i<4;i++)
	{
		for (j=0;j<4;j++)
		{
			tmp[i][j]=p->tableau[i][j];
		}
	}

    /* on fait la rotation et on recopie dans la piece */
    for(i=0;i<4;i++)
    {
	for (j=0;j<4;j++)
	{
		p->tableau[j][3-i]=tmp[i][j];
	}
    }
}

/**
* \brief Renvoie si la case est VIDE ou non
* \details A partir d'assert, on verifie que la case est dans la piece
* \param p Pointeur sur Piece (constante)
* \param x Numero de la ligne
* \param y Numero de la colonne
* \return Un \e entier correspondant a l'etat de la case souhaitee
*/
Etat GetEtatPiece(const Piece* p, int x, int y)
{
	/*on verifie que la case est dans le piece */
	assert(x>=0);
	assert(y>=0);
	assert(x<4);
	assert(y<4);

	/*on retourne l'etat de la case demandee */
	return(p->tableau[x][y]);
}

/**
* \brief Efface la piece
* \param p Pointeur sur Piece
*/
void LiberePiece(Piece * p)
{
	int i,j;

	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			/*efface la piece */
			p->tableau[i][j]=VIDE;
		}
	}
	/*on libere la memoire */
	free(p);
}
